package com.yourenbang.lingyun.transaction.web.service.impl.ticket;

import com.yourenbang.lingyun.constants.BizCodeMessages;
import com.yourenbang.lingyun.constants.enums.PlatNoEnums;
import com.yourenbang.lingyun.constants.enums.table.AllyTicketEnum;
import com.yourenbang.lingyun.core.message.Result;
import com.yourenbang.lingyun.core.util.BizAssertUtils;
import com.yourenbang.lingyun.core.util.KLog;
import com.yourenbang.lingyun.core.util.StringUtils;
import com.yourenbang.lingyun.core.util.date.DateFormat;
import com.yourenbang.lingyun.core.util.date.LocalDateUtils;
import com.yourenbang.lingyun.domain.*;
import com.yourenbang.lingyun.mapper.*;
import com.yourenbang.lingyun.transaction.web.domain.dto.fund.AllyTicketDTO;
import com.yourenbang.lingyun.transaction.web.domain.vo.fund.AllyTicketVO;
import com.yourenbang.lingyun.transaction.web.service.CommonService;
import com.yourenbang.lingyun.transaction.web.service.ticket.TicketAccountService;
import com.yourenbang.transaction.api.model.dto.ticket.AddTicketDTO;
import com.yourenbang.transaction.api.service.ticket.TicketApiService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * @Description
 * @Date 2021/4/25 18:04
 * @Created by Jason
 */
@Slf4j
@RestController
public class TicketApiServiceImpl implements TicketApiService {

    @Autowired
    private Terminal21Mapper terminal21Mapper;
    @Autowired
    private TerminalMapper terminalMapper;
    @Autowired
    private AllyTicket21Mapper allyTicket21Mapper;
    @Autowired
    private AllyTicket20Mapper allyTicket20Mapper;
    @Autowired
    private UserBaseMapper userBaseMapper;
    @Autowired
    private Merchant21Mapper merchant21Mapper;
    @Autowired
    private Merchant20Mapper merchant20Mapper;
    @Autowired
    private TicketAccountService ticketAccountService;
    @Autowired
    private AllyTicketJournal21Mapper allyTicketJournal21Mapper;
    @Autowired
    private AllyTicketJournal20Mapper allyTicketJournal20Mapper;
    @Autowired
    private CommonService commonService;

    private final static Integer TICKET_AMOUNT_ONE = 1;
    private final static LocalDateTime TICKET_EXPIRED_TIME = LocalDateUtils.stringToLocalDateTime("2026-12-31 23:59:59");
    @Override
    public Result<Void> addTicket(AddTicketDTO dto) {
        try {

            KLog.info("插入积分兑换券入参:{}", dto.toJSON());
            //防重复提交
            if (commonService.repeatSubmit("addTicket:" + dto.getUserBaseId() + "-" + dto.getTerminalSn() +"-"+dto.getChannelId())) {
                return Result.builder().fail(BizCodeMessages.VALIDATOR_REPEAT_SUBMIT);
            }
            //查询是否发放过兑换券
            AllyTicketJournal21Example allyTicketJournal21Example = new AllyTicketJournal21Example();
            allyTicketJournal21Example.createCriteria().andFromUserBaseIdEqualTo(dto.getUserBaseId())
                    .andChannelIdEqualTo(dto.getChannelId()).andJournalTypeEqualTo(AllyTicketEnum.TicketJournalTypeEnum.REWARD.getCode());
            long l = allyTicketJournal21Mapper.countByExample(allyTicketJournal21Example);
            if (l > 0) {
                KLog.error("兑换券重复发放已拦截,请排查:{}",dto.toJSON());
                return Result.builder().fail(BizCodeMessages.TRANSACTION_SCORE_ADDED);
            }


            //保存积分兑换券
            AllyTicket21 allyTicket21 = new AllyTicket21();
            Terminal21Example terminal21Example = new Terminal21Example();
            if (StringUtils.isNotBlank(dto.getTerminalSn())) {
                terminal21Example.createCriteria().andBindUserBaseIdEqualTo(dto.getUserBaseId()).andTerminalSnEqualTo(dto.getTerminalSn())
                        .andPlatNoEqualTo(PlatNoEnums.YXY.getCode()).andChannelIdEqualTo(dto.getChannelId());
            } else {
                terminal21Example.createCriteria().andBindUserBaseIdEqualTo(dto.getUserBaseId())
                        .andPlatNoEqualTo(PlatNoEnums.YXY.getCode()).andChannelIdEqualTo(dto.getChannelId());
            }

            List<Terminal21> terminal21s = terminal21Mapper.selectByExample(terminal21Example);
            if (CollectionUtils.isEmpty(terminal21s)) {
                KLog.error("yxy激活返积分兑换券查询不到机具:{}", dto.toJSON());
                return Result.builder().fail(BizCodeMessages.TERMINAL_TRANSFER_SN_ERROR);
            }
            Terminal21 terminal21 = terminal21s.get(0);
            if (terminal21.getPolicyInvalidTime().isBefore(LocalDateTime.now())) {
                KLog.info("兑换券奖励时间已过,不奖励:{}",dto.toJSON());
                return Result.builder().success();
            }
            //先查询此人原来有多少张
            AllyTicketDTO allyTicketDTO = new AllyTicketDTO();
            allyTicketDTO.setUserBaseId(dto.getToUserBaseId());
            allyTicketDTO.setPlatNo(dto.getPlatNo());
            Result<AllyTicketVO> result = ticketAccountService.allyTicketYxy(allyTicketDTO);
            AllyTicketVO allyTicketVO = result.getData();
            int useableBefore = allyTicketVO.getTicketUseable();

            allyTicket21.setUserBaseId(dto.getToUserBaseId());
            allyTicket21.setFromUserBaseId(dto.getUserBaseId());
            allyTicket21.setOriginalAllyUserBaseId(dto.getToUserBaseId());
            allyTicket21.setTicketName(AllyTicketEnum.TicketAmountEnum.YRB_TICKET_200.getName());
            allyTicket21.setTicketAmount(AllyTicketEnum.TicketAmountEnum.YRB_TICKET_200.getAmount());
            allyTicket21.setTicketStatus(AllyTicketEnum.StatusEnum.STATUS_USEABLE.getCode());
            LocalDateTime now = LocalDateTime.now();
            allyTicket21.setEffectiveTime(now);
            allyTicket21.setTicketExpirationTime(TICKET_EXPIRED_TIME);
            allyTicket21.setRewardExpirationTime(terminal21.getRefundOutTime());
            allyTicket21.setChannelId(dto.getChannelId());
            allyTicket21.setPlatNo(dto.getPlatNo());
            int i = allyTicket21Mapper.insertSelective(allyTicket21);
            BizAssertUtils.assertOne(i, "插入积分兑换券失败");

            //保存积分兑换券流水
            AllyTicketJournal21 allyTicketJournal21 = new AllyTicketJournal21();

            allyTicketJournal21.setFromUserBaseId(dto.getUserBaseId());

            Merchant21Example merchant21Example = new Merchant21Example();
            merchant21Example.createCriteria().andUserBaseIdEqualTo(dto.getUserBaseId()).andPlatNoEqualTo(dto.getPlatNo())
                    .andChannelIdEqualTo(dto.getChannelId());
            List<Merchant21> merchant21s = merchant21Mapper.selectByExample(merchant21Example);

            if (CollectionUtils.isNotEmpty(merchant21s)) {
                allyTicketJournal21.setFromUserName(merchant21s.get(0).getRealName());
            }

            allyTicketJournal21.setToUserBaseId(dto.getToUserBaseId());
            UserBase toUserBase = userBaseMapper.selectByPrimaryKey(dto.getToUserBaseId());
            if (!Objects.isNull(toUserBase)) {
                allyTicketJournal21.setToUserName(toUserBase.getUserName());
            }

            allyTicketJournal21.setJournalName(AllyTicketEnum.TicketJournalTypeEnum.REWARD.getMsg());
            allyTicketJournal21.setJournalType(AllyTicketEnum.TicketJournalTypeEnum.REWARD.getCode());
            allyTicketJournal21.setChangeValue(TICKET_AMOUNT_ONE);
            allyTicketJournal21.setTicketAmountBefore(useableBefore);
            allyTicketJournal21.setTicketAmountAfter(useableBefore + TICKET_AMOUNT_ONE);
            allyTicketJournal21.setChannelId(dto.getChannelId());
            allyTicketJournal21.setPlatNo(dto.getPlatNo());
            allyTicketJournal21.setCreateMonth(LocalDateUtils.nowByFormat(DateFormat.DATE_MONTH.getPartten()));
            int i1 = allyTicketJournal21Mapper.insertSelective(allyTicketJournal21);
            BizAssertUtils.assertOne(i1, "插入积分兑换券流水失败");

        } catch (Exception e) {
            KLog.error("增加积分兑换券失败:{}", dto.toJSON(), e);
        }
        return Result.builder().success();
    }

    @Override
    public Result<Void> addTicketKlks(AddTicketDTO dto) {

        KLog.info("插入积分兑换券入参:{}", dto.toJSON());

        try {
            //保存积分兑换券
            AllyTicket20 allyTicket20 = new AllyTicket20();
            TerminalExample terminal20Example = new TerminalExample();
            terminal20Example.createCriteria().andBindUserBaseIdEqualTo(dto.getUserBaseId())
                    .andPlatNoEqualTo(PlatNoEnums.KLKS.getCode()).andChannelIdEqualTo(dto.getChannelId());
            List<Terminal> terminal20s = terminalMapper.selectByExample(terminal20Example);
            if (CollectionUtils.isEmpty(terminal20s)) {
                KLog.error("klks激活返积分兑换券查询不到机具:{}", dto.toJSON());
                return Result.builder().fail(BizCodeMessages.TERMINAL_TRANSFER_SN_ERROR);
            }
            Terminal terminal20 = terminal20s.get(0);
            if (terminal20.getPolicyInvalidTime().isBefore(LocalDateTime.now())) {
                KLog.info("兑换券奖励时间已过,不奖励:{}",dto.toJSON());
                return Result.builder().success();
            }
            //先查询此人原来有多少张
            AllyTicketDTO allyTicketDTO = new AllyTicketDTO();
            allyTicketDTO.setUserBaseId(dto.getToUserBaseId());
            allyTicketDTO.setPlatNo(dto.getPlatNo());
            Result<AllyTicketVO> result = ticketAccountService.allyTicketKlks(allyTicketDTO);
            AllyTicketVO allyTicketVO = result.getData();
            int useableBefore = allyTicketVO.getTicketUseable();

            allyTicket20.setUserBaseId(dto.getToUserBaseId());
            allyTicket20.setFromUserBaseId(dto.getUserBaseId());
            allyTicket20.setOriginalAllyUserBaseId(dto.getToUserBaseId());
            allyTicket20.setTicketName(AllyTicketEnum.TicketAmountEnum.KLKS_TICKET_129.getName());
            allyTicket20.setTicketAmount(AllyTicketEnum.TicketAmountEnum.KLKS_TICKET_129.getAmount());
            allyTicket20.setTicketStatus(AllyTicketEnum.StatusEnum.STATUS_USEABLE.getCode());

            allyTicket20.setEffectiveTime(LocalDateTime.now());
            allyTicket20.setTicketExpirationTime(terminal20.getPolicyInvalidTime());
            allyTicket20.setRewardExpirationTime(terminal20.getRefundOutTime());
            allyTicket20.setChannelId(dto.getChannelId());
            allyTicket20.setPlatNo(dto.getPlatNo());
            int i = allyTicket20Mapper.insertSelective(allyTicket20);
            BizAssertUtils.assertOne(i, "插入积分兑换券失败");

            //保存积分兑换券流水
            AllyTicketJournal20 allyTicketJournal20 = new AllyTicketJournal20();

            allyTicketJournal20.setFromUserBaseId(dto.getUserBaseId());

            Merchant20Example merchant20Example = new Merchant20Example();
            merchant20Example.createCriteria().andUserBaseIdEqualTo(dto.getUserBaseId()).andPlatNoEqualTo(dto.getPlatNo())
                    .andChannelIdEqualTo(dto.getChannelId());
            List<Merchant20> merchant20s = merchant20Mapper.selectByExample(merchant20Example);

            if (CollectionUtils.isNotEmpty(merchant20s)) {
                allyTicketJournal20.setFromUserName(merchant20s.get(0).getRealName());
            }

            allyTicketJournal20.setToUserBaseId(dto.getToUserBaseId());
            UserBase toUserBase = userBaseMapper.selectByPrimaryKey(dto.getToUserBaseId());
            if (!Objects.isNull(toUserBase)) {
                allyTicketJournal20.setToUserName(toUserBase.getUserName());
            }

            allyTicketJournal20.setJournalName(AllyTicketEnum.TicketJournalTypeEnum.REWARD.getMsg());
            allyTicketJournal20.setJournalType(AllyTicketEnum.TicketJournalTypeEnum.REWARD.getCode());
            allyTicketJournal20.setChangeValue(1);
            allyTicketJournal20.setTicketAmountBefore(useableBefore);
            allyTicketJournal20.setTicketAmountAfter(useableBefore + 1);
            allyTicketJournal20.setChannelId(dto.getChannelId());
            allyTicketJournal20.setPlatNo(dto.getPlatNo());
            allyTicketJournal20.setCreateMonth(LocalDateUtils.nowByFormat(DateFormat.DATE_MONTH.getPartten()));
            int i1 = allyTicketJournal20Mapper.insertSelective(allyTicketJournal20);
            BizAssertUtils.assertOne(i1, "插入积分兑换券流水失败");

        } catch (Exception e) {
            KLog.error("增加积分兑换券失败:{}", dto.toJSON(), e);
        }
        return Result.builder().success();
    }
}
